#ifndef __WIZ_GEOMETRY_TRIANGLE_HPP__SHANHAOBO_19800429__
#define __WIZ_GEOMETRY_TRIANGLE_HPP__SHANHAOBO_19800429__

#include "../../WizAlgebra/Include/Utils/WizAlgebraUtils.hpp"
#include "../../WizAlgebra/Include/Linear/Vector3/WizAlgebraVector3.hpp"

#include "./WizGeometryEnums.hpp"

namespace Wiz
{
    namespace Triangle3D
    {
        template<class ElementT>
        struct Type;
    } /// end of namespace Triangle3D

    namespace Triangle3DRef
    {
        template<class ElementT>
        struct Type;
    } /// end of namespace Triangle3DRef

    namespace Triangle2D
    {
        template<class ElementT>
        struct WIZ_EXPORT Type
        {
        private:
            WIZ_DECLARE_CLASS_THIS(Type);
            typedef ElementT                                tElement;
            typedef ::Wiz::Vector2::Type<tElement>    tPosition;
            typedef ::Wiz::Vector2::Type<tElement>    tVector2;
            typedef tPosition&                              tPositionRef;
            typedef const tPosition&                        tPositionIn;
            typedef tPosition&                              tPositionOut;
            friend ::Wiz::Triangle3D::Type<tElement>;
            friend ::Wiz::Triangle3DRef::Type<tElement>;
            //////////////////////////////////////////////////////////////////////////
            tPosition    m_Pos0, m_Pos1, m_Pos2;
        public:
            Type()
            {
            }
            Type(tPositionIn In0, tPositionIn In1, tPositionIn In2) : m_Pos0(In0), m_Pos1(In1), m_Pos2(In2)
            {
            }
        public:
            ::Wiz::Bool::Type IsIn(tPositionIn InTest) const
            {
                return this->IsIn(InTest, m_Pos0, m_Pos1, m_Pos2);
            }
            ::Wiz::Bool::Type IsIn2(tPositionIn InTest) const
            {
                return this->IsIn2(InTest, m_Pos0, m_Pos1, m_Pos2);
            }
        public:
            static ::Wiz::Bool::Type IsIn(tPositionIn InTest, tPositionIn InPos0, tPositionIn InPos1, tPositionIn InPos2);
            static ::Wiz::Bool::Type IsIn2(tPositionIn InTest, tPositionIn InPos0, tPositionIn InPos1, tPositionIn InPos2);
        };
    } /// end of namespace Triangle2D

    namespace Triangle2DRef
    {
        template<class ElementT>
        struct WIZ_EXPORT Type
        {
        private:
            typedef ElementT                                tElement;
            typedef Type                                    tThis;
            typedef ::Wiz::Vector2::Type<tElement>    tPosition;
            typedef ::Wiz::Vector2::Type<tElement>    tVector2;
            typedef tPosition&                              tPositionRef;
            typedef const tPosition&                        tPositionRefConst;
            typedef const tPosition&                        tPositionIn;
            typedef tPosition&                              tPositionOut;
            //////////////////////////////////////////////////////////////////////////
            mutable tPositionRefConst    m_Pos0, m_Pos1, m_Pos2;
        public:
            Type(tPositionIn In0, tPositionIn In1, tPositionIn In2) : m_Pos0(In0), m_Pos1(In1), m_Pos2(In2)
            {
            }
        public:
            ::Wiz::Bool::Type IsIn(tPositionIn InTest) const
            {
                return this->IsIn(InTest, m_Pos0, m_Pos1, m_Pos2);
            }
            ::Wiz::Bool::Type IsIn2(tPositionIn InTest) const
            {
                return this->IsIn2(InTest, m_Pos0, m_Pos1, m_Pos2);
            }
        public:
            static ::Wiz::Bool::Type IsIn(tPositionIn InTest, tPositionIn InPos0, tPositionIn InPos1, tPositionIn InPos2);
            static ::Wiz::Bool::Type IsIn2(tPositionIn InTest, tPositionIn InPos0, tPositionIn InPos1, tPositionIn InPos2);
        };
    } /// end of namespace Triangle2DRef

    //////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////

    namespace Triangle3D
    {
        template<class ElementT>
        struct WIZ_EXPORT Type
        {
        private:
            WIZ_DECLARE_CLASS_THIS(Type);
            typedef ElementT                                tElement;
            typedef ::Wiz::Triangle2D::Type<tElement> tTriangle2D;
            typedef ::Wiz::Vector3::Type<tElement>    tPosition;
            typedef ::Wiz::Vector3::Type<tElement>    tVector3;
            typedef tPosition&                              tPositionRef;
            typedef const tPosition&                        tPositionIn;
            typedef tPosition&                              tPositionOut;

            //////////////////////////////////////////////////////////////////////////
            tPosition    m_Pos0, m_Pos1, m_Pos2;
        public:
            Type()
            {
            }
            Type(tPositionIn In0, tPositionIn In1, tPositionIn In2) : m_Pos0(In0), m_Pos1(In1), m_Pos2(In2)
            {
            }
        public:
            ::Wiz::Bool::Type IsIn(tPositionIn InTest) const
            {
                return this->IsIn(InTest, m_Pos0, m_Pos1, m_Pos2);
            }
        public:
        public:
            static ::Wiz::Axis::Type  GetMainAxisTriangle(tTriangle2D& OutTri, tPositionIn InTest, tPositionIn InPos0, tPositionIn InPos1, tPositionIn InPos2);
            static ::Wiz::Bool::Type        IsIn(tPositionIn InTest, tPositionIn InPos0, tPositionIn InPos1, tPositionIn InPos2);
        };
    } /// end of namespace Triangle3D

    namespace Triangle3DRef
    {
        template<class ElementT>
        struct WIZ_EXPORT Type
        {
        private:
            typedef ElementT                                tElement;
            typedef Type                                    tThis;
            typedef ::Wiz::Triangle2D::Type<tElement> tTriangle2D;
            typedef ::Wiz::Vector3::Type<tElement>    tPosition;
            typedef ::Wiz::Vector3::Type<tElement>    tVector3;
            typedef tPosition&                              tPositionRef;
            typedef const tPosition&                        tPositionRefConst;
            typedef const tPosition&                        tPositionIn;
            typedef tPosition&                              tPositionOut;

            //////////////////////////////////////////////////////////////////////////
            mutable tPositionRefConst    m_Pos0, m_Pos1, m_Pos2;
        public:
            Type(tPositionIn In0, tPositionIn In1, tPositionIn In2) : m_Pos0(In0), m_Pos1(In1), m_Pos2(In2)
            {
            }
        public:
            ::Wiz::Bool::Type IsIn(tPositionIn InTest) const
            {
                return this->IsIn(InTest, m_Pos0, m_Pos1, m_Pos2);
            }
        public:
        public:
            static ::Wiz::Axis::Type  GetMainAxisTriangle(tTriangle2D& OutTri, tPositionIn InTest, tPositionIn InPos0, tPositionIn InPos1, tPositionIn InPos2);
            static ::Wiz::Bool::Type        IsIn(tPositionIn InTest, tPositionIn InPos0, tPositionIn InPos1, tPositionIn InPos2);
        };
    } /// end of namespace Triangle3DRef
} /// end of namespace Wiz

#endif /*__WIZ_GEOMETRY_TRIANGLE_HPP__SHANHAOBO_19800429__*/


